////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011-2012 www.iflytek.com. All Rights Reserved.
//  This software for customer relationship management system, developed by Noo team.
//  Software code and design for the team, copy rights reserved.
////////////////////////////////////////////////////////////////////////////////

package com.iflytek.ci.cpms.service.impl;

import com.google.common.collect.Maps;
import com.iflytek.ci.common.service.ToolsService;
import com.iflytek.ci.common.utils.excel.Excels;
import com.iflytek.ci.cpms.dao.MilestoneDao;
import com.iflytek.ci.cpms.dao.ProjectDao;
import com.iflytek.ci.cpms.dao.ProjectUserBatchDao;
import com.iflytek.ci.cpms.dao.TeamAccountMapDao;
import com.iflytek.ci.cpms.dao.TeamDao;
import com.iflytek.ci.cpms.domain.Project;
import com.iflytek.ci.cpms.domain.Team;
import com.iflytek.ci.cpms.dto.ProjectInformation;
import com.iflytek.ci.cpms.service.MilestoneService;
import com.iflytek.ci.cpms.service.ProjectService;
import com.iflytek.ci.cums.dto.ProjectAccount;
import com.iflytek.ci.cums.service.AccountService;
import com.iflytek.ci.cums.service.TeamService;
import com.iflytek.ci.cums.service.impl.ShiroDbRealm;
import com.iflytek.ci.cums.util.ProjectAddExcelParser;
import com.iflytek.ci.main.dao.SerialNumberDao;
import com.iflytek.ci.main.domain.SerialNumber;
import com.iflytek.ci.qams.dao.IssueDao;
import com.iflytek.framework.pagination.PaginationCriteria;
import com.iflytek.framework.pagination.PaginationResult;
import org.apache.commons.io.FileUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 项目接口实现
 * 
 * @author mdzhang
 * @version 1.0 2012-10-30 10:47 AM
 * @since JDK 1.5
 */
@Service("projectService")
@Transactional(readOnly = true,isolation = Isolation.READ_UNCOMMITTED)
public class ProjectServiceImpl implements ProjectService {
	/** 项目DAO接口 */
	@Autowired
	private ProjectDao projectdao;
	/** 流水号DAO */
	@Autowired
	private SerialNumberDao serialNumberDao;

	@Autowired
	private IssueDao issueDao;
	/** 项目团队服务 */
	@Autowired
	private TeamService teamService;
	/** 项目团队服务 */
	@Autowired
	private ProjectDao projectDao;
	/** 项目团队服务 */
	@Autowired
	private TeamDao teamDao;
	/** tools服务 */
	@Autowired
	private ToolsService toolsService;
	@Autowired
	/**milestone服务*/
	private MilestoneDao milestoneDao;
	@Autowired
	private ProjectUserBatchDao projectUserBatchDao;
	@Autowired
	private TeamAccountMapDao teamAccountMapDao;
	private static final Logger LOGGER = LoggerFactory
			.getLogger(AccountService.class);

	@Override
	public PaginationResult<Project> find_project(PaginationCriteria criteria) {
		ShiroDbRealm.ShiroUser shiro = (ShiroDbRealm.ShiroUser) SecurityUtils
				.getSubject().getPrincipal();
		String login = shiro.getLogin();
		PaginationResult<Project> project;
		if (SecurityUtils.getSubject().hasRole("Admin")) {
			project = projectdao.pageProject(criteria);
		} else {
			project = projectdao.page_project_leader(criteria, login);
		}
		return project;
	}

	@Override
	public List<Project> fuzzySearchProjects(String key) {
		return projectdao.fuzzy_search_projects(key);
	}

	@Override
	public ProjectInformation getProjectInformation(long pid) {
		return projectdao.getPrjectInformation(pid);
	}

    @Transactional
    @Override
    public void add_project(Project project, long[] team_account_ids,String basePath,String realPath) {
        // 创建项目团队
        final Team team = new Team();
        team.setName(project.getCode() + "-team");
        team.setDescription(project.getName() + "项目开发团队");
        teamService.add_team(team, team_account_ids);
        // 处理项目流水
        SerialNumber serialNumber = new SerialNumber();
        serialNumber.setKey(project.getCode());
        serialNumber.setSn(1);
        serialNumberDao.insert_serial_number(serialNumber);

        Date now = new Date();
        project.setCreate(now);
        project.setTeam(team.getId());
        if(project.getDev_leader()==""){
            project.setDev_leader(project.getLead());
        }
        //设置集成工具访问地址
        String url= basePath+"action/tools/"+project.getCode()+"_tools.js";
        String toolString="(function(){ var toolscript = document.createElement('script');\ntoolscript.type = 'text/javascript'; toolscript.async = true;\n" +
                " toolscript.src='"+url;
        toolString+="';\n var firstNode = document.getElementsByTagName('script')[0]; \nfirstNode.parentNode.insertBefore(toolscript, firstNode);\n})();";

        toolsService.create_new_tools_js(project, basePath,realPath,toolString);
        toolString="<script type=\"text/javascript\">\n"+toolString;
        toolString+="</script>";
        project.setTool_url(toolString);
        projectdao.add_project(project);
    }

	@Transactional
	@Override
	public void assign_lead(long project_id, String lead) {
		final Map<String, Object> map = Maps.newHashMap();
		map.put("id", project_id);
		Project project = projectdao.getProject(map);
		project.setLead(lead);
		projectdao.updateProject(project);
	}

	@Transactional
	@Override
	public void assign_team(long project_id, long team_id) {
		final Map<String, Object> map = Maps.newHashMap();
		map.put("id", project_id);
		Project project = projectdao.getProject(map);
		project.setTeam(team_id);
		projectdao.updateProject(project);
	}

	@Transactional
	@Override
	public boolean remove_project(String[] project_ids) {
		for (String project_id : project_ids) {
			Object selectResult = issueDao.getTop(Long.valueOf(project_id));
			if (selectResult != null) {
				return false;
			}
		}
		serialNumberDao.delete_sn_with_projects(project_ids);
        String [] project_keys = projectdao.get_Keys_by_ids(project_ids);
        toolsService.delete_tools_js(project_keys);
		projectdao.delete_project(project_ids);
		teamService.remove_team_with_projects(project_ids);
		milestoneDao.delete_with_pids(project_ids);
		return true;
	}

	@Override
	public Project fromKey(String pkey) {
		final Map<String, Object> params = Maps.newHashMap();
		params.put("code", pkey);
		return projectdao.getProject(params);
	}


	@Override
	public PaginationResult<Project> search_project(
			PaginationCriteria criteria, Map<String, Object> params) {
		return projectdao.serachProjects(criteria, params);
	}

	@Override
	public PaginationResult<Project> fuzzySearchProjects(
			PaginationCriteria criteria, String search) {

		PaginationResult<Project> project;
		if (SecurityUtils.getSubject().hasRole("Admin")) {
			project = projectdao.fuzzy_page_searcha_projects(criteria, search);
		} else {
			ShiroDbRealm.ShiroUser shiro = (ShiroDbRealm.ShiroUser) SecurityUtils
					.getSubject().getPrincipal();
			String login = shiro.getLogin();
			project = projectdao.fuzzy_page_searcha_projects_login(criteria,
					login, search);
		}
		return project;
	}

	@Override
	public Project get_project(Map<String, Object> params) {
		return projectdao.getProject(params);
	}

	@Transactional
	@Override
	public void update_project(Project project, long[] team_account_ids) {
		// 创建项目团队
		Team team = teamService.get_teamById(project.getTeam());
		if (team == null) {
			team = new Team();
			team.setName(project.getCode() + "-team");
			team.setDescription(project.getName() + "项目开发团队");
		}
		teamService.add_team(team, team_account_ids);
		// 更新项目
		project.setTeam(team.getId());
		projectdao.updateProject(project);
	}

	@Override
	public Project fromId(long id) {
		final Map<String, Object> params = Maps.newHashMap();
		params.put("id", id);
		return projectdao.getProject(params);
	}

	@Override
	public List<Project> all_projects() {
		return projectdao.project_with_text();
	}

	@Override
	public ProjectInformation get_info_milestone_id(long milestone_id) {
		return projectdao.get_project_info(milestone_id);
	}

    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
	@Override
	public void import_account(long pid, MultipartFile upload_file) {
		String[] s = new String[1];
		s[0] = String.valueOf(pid);
		// 删除旧团队
		teamService.remove_team_with_projects(s);
		// 删除旧团队的成员
		teamAccountMapDao.remove_teamAccountMap(projectdao.getTidByPid(pid));
		File file = null;
		// 文件临时目录存放
		try {
			String temp_file_path = System.getProperty("java.io.tmpdir")
					+ File.separator + upload_file.getOriginalFilename();
			file = new File(temp_file_path);
			FileUtils.writeByteArrayToFile(file, upload_file.getBytes());
			List<ProjectAccount> list = (List<ProjectAccount>) Excels
					.readExcel(0, new ProjectAddExcelParser(), temp_file_path);
			Team t = new Team();
			t.setName(projectdao.project_with_id(pid).getCode() + "-team");
			t.setDescription(projectDao.project_with_id(pid).getCode()
					+ "项目开发团队");
			// 新建团队
			teamDao.add_team(t);
			Project project = projectDao.project_with_id(pid);
			// 设置项目团队
			project.setTeam(teamService.getTidByName(t.getName()));
			// 更新团队
			projectDao.updateProject(project);
			// 增加团队成员
			teamAccountMapDao.add_teamAccountMap(projectdao.getTidByPid(pid),
					projectUserBatchDao.idsFromLogins(projectUserBatchDao
							.batch_account(list)));
		} catch (IOException e) {
			LOGGER.error("导入用户数据时文件上传出现异常!", e);
		} finally {
			FileUtils.deleteQuietly(file);
		}

	}

	@Override
	public List<Project> get_project() {
		ShiroDbRealm.ShiroUser shiro = (ShiroDbRealm.ShiroUser) SecurityUtils
				.getSubject().getPrincipal();
		return projectDao.get_all_project_login(shiro.getLogin());
	}

	@Override
	public List<Project> projects_with_ids(String[] ids) {
			return projectdao.projects_with_ids(ids);
	}
}
